#include "LineItem.h"

#include <QtQuick/qsgnode.h>
#include <QtQuick/qsgflatcolormaterial.h>

LineItem::LineItem(QQuickItem *parent)
  : ShapeItem(parent)
  , m_p1(0, 0)
  , m_p2(0, 0)
{
    setFlag(ItemHasContents, true);
}

void LineItem::setP1(const QPointF &p)
{
    if (p == m_p1)
        return;

    m_p1 = p;
    emit p1Changed(p);
    update();
}

void LineItem::setP2(const QPointF &p)
{
    if (p == m_p2)
        return;

    m_p2 = p;
    emit p2Changed(p);
    update();
}

QSGNode *LineItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
{
    QSGGeometryNode *node = 0;
    QSGGeometry *geometry = 0;

    QSGGeometryNode *startNode = 0;
    QSGGeometryNode *endNode = 0;

    QSGGeometry *startGeometry = 0;
    QSGGeometry *endGeometry = 0;

    if (!oldNode) {
        node = new QSGGeometryNode;
        geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 2);
        geometry->setLineWidth(1);
        geometry->setDrawingMode(GL_LINES);
        node->setGeometry(geometry);

        node->setFlag(QSGNode::OwnsGeometry);

        QSGFlatColorMaterial *material = new QSGFlatColorMaterial;
        material->setColor(QColor(255, 255, 0));
        node->setMaterial(material);
        node->setFlag(QSGNode::OwnsMaterial);

        if(m_selected)
        {
            startNode = new QSGGeometryNode;
            startGeometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 4);
            startGeometry->setLineWidth(1);
            startGeometry->setDrawingMode(GL_QUADS);
            startNode->setGeometry(startGeometry);

            endNode = new QSGGeometryNode;
            endGeometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), 4);
            endGeometry->setLineWidth(1);
            endGeometry->setDrawingMode(GL_QUADS);
            endNode->setGeometry(endGeometry);

            QSGFlatColorMaterial *material = new QSGFlatColorMaterial;
            material->setColor(QColor(0, 0, 255));
            startNode->setMaterial(material);
            startNode->setFlag(QSGNode::OwnsMaterial);
            endNode->setMaterial(material);
            endNode->setFlag(QSGNode::OwnsMaterial);

            node->appendChildNode(startNode);
            node->appendChildNode(endNode);
        }
    } else {
        node = static_cast<QSGGeometryNode *>(oldNode);
        geometry = node->geometry();
        geometry->allocate(2);

        if(m_selected)
        {
            startNode = static_cast<QSGGeometryNode *>(node->childAtIndex(0));
            endNode = static_cast<QSGGeometryNode *>(node->childAtIndex(1));
            startGeometry = startNode->geometry();
            startGeometry->allocate(4);
            endGeometry = endNode->geometry();
            endGeometry->allocate(4);
        }
    }


    QSGGeometry::Point2D *vertices = geometry->vertexDataAsPoint2D();
    vertices[0].set(m_p1.x(), m_p1.y());
    vertices[1].set(m_p2.x(), m_p2.y());

    if(m_selected)
    {
        QSGGeometry::Point2D *stVertices = startGeometry->vertexDataAsPoint2D();
        stVertices[0].set(m_p1.x() - 5, m_p1.y() - 5);
        stVertices[1].set(m_p1.x() - 5, m_p1.y() + 5);
        stVertices[2].set(m_p1.x() + 5, m_p1.y() + 5);
        stVertices[3].set(m_p1.x() + 5, m_p1.y() - 5);

        QSGGeometry::Point2D *endVertices = endGeometry->vertexDataAsPoint2D();
        endVertices[0].set(m_p2.x() - 5, m_p2.y() - 5);
        endVertices[1].set(m_p2.x() - 5, m_p2.y() + 5);
        endVertices[2].set(m_p2.x() + 5, m_p2.y() + 5);
        endVertices[3].set(m_p2.x() + 5, m_p2.y() - 5);
    }
    node->markDirty(QSGNode::DirtyGeometry);

    return node;
}
